package com.suxin.utils;

import com.suxin.spring.configuration.ConversionServiceDeducer;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.bind.PlaceholdersResolver;
import org.springframework.boot.context.properties.bind.PropertySourcesPlaceholdersResolver;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.PropertySources;
import org.springframework.stereotype.Component;

import java.util.function.Consumer;

/**
 * @author Tang
 * @classname BinderHolderUtils
 * @description [  ]
 * @date 2023/3/21 16:05
 */
public class BinderHolderUtils {

    private final ApplicationContext applicationContext;

    private final PropertySources propertySources;

    public BinderHolderUtils(PropertySources propertySources,ApplicationContext applicationContext) {
        this.propertySources = propertySources;
        this.applicationContext = applicationContext;
    }

    public Binder getBinder() {
        return new Binder(getConfigurationPropertySource(),getPlaceholdersResolver(),
                getConversionService(),getPropertyEditorInitializer());
    }

    private Iterable<ConfigurationPropertySource> getConfigurationPropertySource() {
        return ConfigurationPropertySources.from(this.propertySources);
    }

    private PlaceholdersResolver getPlaceholdersResolver() {
        return new PropertySourcesPlaceholdersResolver(this.propertySources);
    }

    private ConversionService getConversionService(){
        return new ConversionServiceDeducer(this.applicationContext).getConversionService();
    }

    private Consumer<PropertyEditorRegistry> getPropertyEditorInitializer() {
        if (this.applicationContext instanceof ConfigurableApplicationContext) {
            return ((ConfigurableApplicationContext) this.applicationContext).getBeanFactory()::copyRegisteredEditorsTo;
        }
        return null;
    }

}
